#include "head.h"

// 顺序表的创建
S_arr_list *S_Arr_Init(void)
{
    S_arr_list *L = (S_arr_list *)malloc(sizeof(S_arr_list));
    if (L == NULL)
    {
        printf("顺序表创建失败\n");
        return NULL;
    }
    memset(L->data, 0, ARR_MAX_SIZ * sizeof(F_data));
    L->len = 0;
    return L;
}

// 顺序表的插入
int S_Arr_insert(S_arr_list *L, int pos, F_data data)
{
    if (L == NULL)
    {
        printf("顺序表 为 NULL\n");
        return -1;
    }
    if (L->len >= ARR_MAX_SIZ)
    {
        printf("顺序表已满\n");
        return -1;
    }
    if (pos < 1 || pos > L->len + 1)
    {
        printf("插入位置不合法\n");
        return -1;
    }

    // 从插入点开始后移数据
    for (int i = L->len; i >= pos; i--)
    {
        L->data[i] = L->data[i - 1];
    }

    L->data[pos - 1] = data;
    L->len++;
    return 0;
}

// 顺序表的删除
F_data S_Arr_delete(S_arr_list *L, int pos)
{
    F_data removed_data = {0};

    if (L == NULL)
    {
        printf("顺序表 为 NULL\n");
        return removed_data;
    }
    if (L->len == 0)
    {
        printf("顺序表内无数据\n");
        return removed_data;
    }
    if (pos < 1 || pos > L->len)
    {
        printf("删除位置不合法\n");
        return removed_data;
    }

    removed_data = L->data[pos - 1];

    // 将后续数据前移
    for (int i = pos; i < L->len; i++)
    {
        L->data[i - 1] = L->data[i];
    }

    L->len--;
    return removed_data;
}

// 顺序表的遍历
void S_Arr_printf(S_arr_list *L)
{
    if (L == NULL)
    {
        printf("顺序表 为 NULL\n");
        return;
    }
    if (L->len == 0)
    {
        printf("顺序表内无数据\n");
        return;
    }

    for (int i = 0; i < L->len; i++)
    {
        printf("班次: %d 机型: %s 起点站: %s 终点站: %s 起飞时间: %02d:%02d 到达时间: %02d:%02d 飞行时间: %s 票价: %d 载客量: %d 剩余座位: %d 是否飞: %c\n",
               L->data[i].id, L->data[i].flighttype, L->data[i].startcity, L->data[i].arrivecity,
               L->data[i].starttime[0], L->data[i].starttime[1], L->data[i].arrivetime[0], L->data[i].arrivetime[1],
               L->data[i].flytime, L->data[i].value, L->data[i].maxNUM, L->data[i].leftbuyersa, L->data[i].whetherfly);
    }
}
//===============================================================购票后向文件写入===============================
void S_List_File_print_buy(U_list *list, const char *file_name)
{
    // 安全判断
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }
    if (list->next == NULL)
    {
        printf("链表无数据\n");
        return;
    }

    FILE *fp = fopen(file_name, "w+");
    if (fp == NULL)
    {
        printf("文件创建失败\n");
        return;
    }
    fseek(fp, 0, SEEK_SET);

    U_node *ptr = list->next;

    while (ptr != NULL)
    {
        fprintf(fp, "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数:%d\t",
                ptr->data.name, ptr->data.passwd, ptr->data.grade, ptr->data.value, ptr->data.ticket_num);

        for (int d = ptr->data.ticket_num; d > 0; d--)
        {
            fprintf(fp, "%d\t", ptr->data.ticket[d - 1].id);
            fprintf(fp, "%s\t", ptr->data.ticket[d - 1].flighttype);
            fprintf(fp, "%s\t", ptr->data.ticket[d - 1].startcity);
            fprintf(fp, "%s\t", ptr->data.ticket->arrivecity);
            fprintf(fp, "%d:%d\t", ptr->data.ticket[d - 1].starttime[0], ptr->data.ticket[d - 1].starttime[1]);
            fprintf(fp, "%d:%d\t", ptr->data.ticket[d - 1].arrivetime[0], ptr->data.ticket[d - 1].arrivetime[1]);
            fprintf(fp, "%s\t", ptr->data.ticket[d - 1].flytime);
            fprintf(fp, "%d\t", ptr->data.ticket[d - 1].value);
            fprintf(fp, "%d\t", ptr->data.ticket[d - 1].maxNUM);
            fprintf(fp, "%d\t", ptr->data.ticket[d - 1].leftbuyersa);
            fprintf(fp, "%c\t", ptr->data.ticket[d - 1].whetherfly);
        }
        ptr = ptr->next;
        fprintf(fp, "\n");
    }

    fflush(fp); // 刷新文件

    fclose(fp);
}

// ==========================================================购退后从文件读取用户信息================================
void S_List_File_scanf_buy(U_list *list, const char *file_name)
{
    // 安全判断
    if (list == NULL)
    {
        printf("链表为NULL\n");
        return;
    }

    FILE *fp = fopen(file_name, "r");
    if (fp == NULL)
    {
        printf("文件打开失败\n");
        return;
    }
    // 移动光标
    fseek(fp, 0, SEEK_SET);
    // 清空链表
    S_List_clear(list);

    U_data data;
    char ch = 0;
    int pos = 0;

    // 检测文件行数
    while ((ch = fgetc(fp)) != EOF)
    {
        if (ch == '\n')
        {
            pos++;
        }
    }

    // 移动光标
    fseek(fp, 0, SEEK_SET);

    for (size_t a = 0; a < pos; a++)
    {
        // "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\n"
        fscanf(fp, "用户名:%s\t密码:%s\t身份码:%d\t余额:%d\t票数:%d\n",
               data.name, data.passwd, &data.grade, &data.value, &data.ticket_num);

        for (int i = data.ticket_num; i > 0; i--)
        {
            fscanf(fp, "%d\t", &data.ticket[i - 1].id);
            fscanf(fp, "%s\t", data.ticket[i - 1].flighttype);
            fscanf(fp, "%s\t", data.ticket[i - 1].startcity);
            fscanf(fp, "%s\t", data.ticket[i - 1].arrivecity);
            fscanf(fp, "%d:%d\t", &data.ticket[i - 1].starttime[0], &data.ticket[i - 1].starttime[1]);
            fscanf(fp, "%d:%d\t", &data.ticket[i - 1].arrivetime[0], &data.ticket[i - 1].arrivetime[1]);
            fscanf(fp, "%s\t", data.ticket[i - 1].flytime);
            fscanf(fp, "%d\t", &data.ticket[i - 1].value);
            fscanf(fp, "%d\t", &data.ticket[i - 1].maxNUM);
            fscanf(fp, "%d\t", &data.ticket[i - 1].leftbuyersa);
            fscanf(fp, "%c\n", &data.ticket[i - 1].whetherfly);
        }
        S_List_insert(list, data, a + 1);
    }

    fflush(fp); // 刷新文件

    fclose(fp);
}

//==============================================购退票================================================================
void buy_refund_ticket(U_data data)
{
    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf_buy(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf_buy(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf_buy(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf_buy(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf_buy(p5, ADMIN_FILE);    // 管理员信息文件
    U_list *list = S_List_init();
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)
    F_data d;
    F_list *p = D_List_init(); // 航班指针
    D_List_file_scanf(p);

    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  载客量  剩余座位  是否飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");
    D_List_print(p);
    printf("请输入你要购买的航班班次:");
    scanf("%s", d.flighttype);
    F_node *pm = D_List_find_name(p, d.flighttype); // 查找到的要购买的航班信息指针
    U_node *pt = S_List_find_name(list, data.name); // 查找到总链表中的登录用户指针
    if (pm->data.value > pt->data.value)            // 判断余额是否足够
    {
        printf("余额不足，请去充值");
        return user_pay(data);
    }
    if (pm->data.leftbuyersa == 0)
    {
        printf("此航班已售空\n");
        return buy_refund_ticket(data);
    }
    pm->data.leftbuyersa = pm->data.leftbuyersa - 1; // 飞机剩余座位数减1

    U_node *pr;
    int num;
    switch (pt->data.grade)
    {
    case (2):
        pr = S_List_find_name(p1, data.name);             // 所在登录用户的指针
        pr->data.ticket_num = pr->data.ticket_num + 1;    // 票数加1
        pr->data.value = pr->data.value - pm->data.value; // 买机票扣钱
        num = pr->data.ticket_num;
        pr->data.ticket[num - 1] = pm->data;     // 把机票信息插入用户中
        S_List_File_print_buy(p1, REGULAR_FILE); // 写入用户文件
        D_List_file_print(p);                    // 写入航班文件
        break;

    case (3):
        pr = S_List_find_name(p2, data.name);             // 所在登录用户的指针
        pr->data.ticket_num = pr->data.ticket_num + 1;    // 票数加1
        pr->data.value = pr->data.value - pm->data.value; // 买机票扣钱
        num = pr->data.ticket_num;
        pr->data.ticket[num - 1] = pm->data;    // 把机票信息插入用户中
        S_List_File_print_buy(p2, SILVER_FILE); // 写入用户文件
        D_List_file_print(p);                   // 写入航班文件
        break;

    case (4):
        pr = S_List_find_name(p3, data.name);             // 所在登录用户的指针
        pr->data.ticket_num = pr->data.ticket_num + 1;    // 票数加1
        pr->data.value = pr->data.value - pm->data.value; // 买机票扣钱
        num = pr->data.ticket_num;
        pr->data.ticket[num - 1] = pm->data;  // 把机票信息插入用户中
        S_List_File_print_buy(p3, GOLD_FILE); // 写入用户文件
        D_List_file_print(p);                 // 写入航班文件
        break;

    case (5):
        pr = S_List_find_name(p4, data.name);             // 所在登录用户的指针
        pr->data.ticket_num = pr->data.ticket_num + 1;    // 票数加1
        pr->data.value = pr->data.value - pm->data.value; // 买机票扣钱
        num = pr->data.ticket_num;
        pr->data.ticket[num - 1] = pm->data;      // 把机票信息插入用户中
        S_List_File_print_buy(p4, PLATINUM_FILE); // 写入用户文件
        D_List_file_print(p);                     // 写入航班文件
        break;

    default:
        break;
    }

    // F_list *p = D_List_init();
    //     D_List_file_scanf(p);
    sleep(3);
    system("clear");

    return user(p, data);
}
//============================================================退票=================================
void refund_ticket(U_data data)
{
    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf_buy(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf_buy(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf_buy(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf_buy(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf_buy(p5, ADMIN_FILE);    // 管理员信息文件
    // int a;
    //    // 用户信息合表
    U_list *list = S_List_init();
    // list = S_List_merge(list,p1);    // 管理员账户信息文件
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)
    F_list *p = D_List_init();     // 航班指针
    F_data mk;
    D_List_file_scanf(p);

    U_node *pt = S_List_find_name(list, data.name); // 查找到总链表中的登录用户指针
    if (pt->data.ticket_num == 0)
    {
        system("clear");
        printf("你还未购票，无法退票\n");
        sleep(3);
        system("clear");

        return user(p, data);
    }
    // check_information(data);
    printf("用户名:%s\t身份码:%d\n", pt->data.name, pt->data.grade);
    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  载客量  剩余座位  是否飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");

    if (pt->data.ticket_num == 0)
    {
        printf("订单为空\n");
    }
    for (int i = pt->data.ticket_num; i > 0; i--)
    {
        printf("%d\t", pt->data.ticket[i - 1].id);
        printf("%s\t", pt->data.ticket[i - 1].flighttype);
        printf("%s\t", pt->data.ticket[i - 1].startcity);
        printf("%s\t", pt->data.ticket[i - 1].arrivecity);
        printf("%d:%d\t", pt->data.ticket[i - 1].starttime[0], pt->data.ticket[i - 1].starttime[1]);
        printf("%d:%d\t", pt->data.ticket[i - 1].arrivetime[0], pt->data.ticket[i - 1].arrivetime[1]);
        printf("%s\t", pt->data.ticket[i - 1].flytime);
        printf("%d\t", pt->data.ticket[i - 1].value);
        printf("%d\t", pt->data.ticket[i - 1].maxNUM);
        printf("%d\t", pt->data.ticket[i - 1].leftbuyersa);
        printf("%c\n", pt->data.ticket[i - 1].whetherfly);
    }
    F_list *pk = D_List_init();
    D_List_file_scanf(pk);

    printf("请输入你要退票的机型\n");
    scanf("%s", mk.flighttype);
    F_node *pm = D_List_find_name(p, mk.flighttype); // 查找到的要购买的航班信息指针
    pm->data.leftbuyersa = pm->data.leftbuyersa + 1; // 座位数加1
    U_node *pr;
    switch (pt->data.grade)
    {
    case (2):
        pr = S_List_find_name(p1, data.name);             // 所在登录用户的指针
        pr->data.value = pr->data.value + pm->data.value; // 退钱给用户
        D_List_file_print(p);                             // 写入航班文件
        for (int k = 0; k < pr->data.ticket_num; k++)     // 删除用户的机票信息
        {
            if (pr->data.ticket[k].id == pm->data.id)
            {
                for (int f = k; f < pr->data.ticket_num; f++)
                {
                    pr->data.ticket[f] = pr->data.ticket[f + 1];
                }
                pr->data.ticket_num = pr->data.ticket_num - 1; // 票数减1
            }
        }
        S_List_File_print_buy(p1, REGULAR_FILE); // 写入用户文件

        break;
    case (3):
        pr = S_List_find_name(p2, data.name);             // 所在登录用户的指针
        pr->data.value = pr->data.value + pm->data.value; // 退钱给用户
        D_List_file_print(p);                             // 写入航班文件
        for (int k = 0; k < pr->data.ticket_num; k++)     // 删除用户的机票信息
        {
            if (pr->data.ticket[k].id == pm->data.id)
            {
                for (int f = k; f < pr->data.ticket_num; f++)
                {
                    pr->data.ticket[f] = pr->data.ticket[f + 1];
                }
                pr->data.ticket_num = pr->data.ticket_num - 1; // 票数减1
            }
        }
        S_List_File_print_buy(p2, SILVER_FILE); // 写入用户文件
        break;
    case (4):
        pr = S_List_find_name(p3, data.name);             // 所在登录用户的指针
        pr->data.value = pr->data.value + pm->data.value; // 退钱给用户
        D_List_file_print(p);                             // 写入航班文件
        for (int k = 0; k < pr->data.ticket_num; k++)     // 删除用户的机票信息
        {
            if (pr->data.ticket[k].id == pm->data.id)
            {
                for (int f = k; f < pr->data.ticket_num; f++)
                {
                    pr->data.ticket[f] = pr->data.ticket[f + 1];
                }
                pr->data.ticket_num = pr->data.ticket_num - 1; // 票数减1
            }
        }
        S_List_File_print_buy(p3, GOLD_FILE); // 写入用户文件
        break;
    case (5):
        pr = S_List_find_name(p4, data.name);             // 所在登录用户的指针
        pr->data.value = pr->data.value + pm->data.value; // 退钱给用户
        D_List_file_print(p);                             // 写入航班文件
        for (int k = 0; k < pr->data.ticket_num; k++)     // 删除用户的机票信息
        {
            if (pr->data.ticket[k].id == pm->data.id)
            {
                for (int f = k; f < pr->data.ticket_num; f++)
                {
                    pr->data.ticket[f] = pr->data.ticket[f + 1];
                }
                pr->data.ticket_num = pr->data.ticket_num - 1; // 票数减1
            }
        }
        S_List_File_print_buy(p4, PLATINUM_FILE); // 写入用户文件
        break;
    default:
        break;
    }
    // F_list *p = D_List_init();
    //     D_List_file_scanf(p);
    sleep(3);
    system("clear");
    return user(p, data);
}
//==============================================查看订单========================================================
void check_information(U_data data)
{
    U_list *p1 = S_List_init();
    U_list *p2 = S_List_init();
    U_list *p3 = S_List_init();
    U_list *p4 = S_List_init();
    U_list *p5 = S_List_init();
    S_List_File_scanf_buy(p1, REGULAR_FILE);  // 普通用户信息文件
    S_List_File_scanf_buy(p2, SILVER_FILE);   // 银卡会员信息文件 (9折)
    S_List_File_scanf_buy(p3, GOLD_FILE);     // 金卡会员信息文件 (8折)
    S_List_File_scanf_buy(p4, PLATINUM_FILE); // 白金会员信息文件 (7折)
    S_List_File_scanf_buy(p5, ADMIN_FILE);    // 管理员信息文件
    // int a;
    //    // 用户信息合表
    U_list *list = S_List_init();
    // list = S_List_merge(list,p1);    // 管理员账户信息文件
    list = S_List_merge(list, p1); // 普通用户信息文件
    list = S_List_merge(list, p2); // 银卡会员信息文件 (9折)
    list = S_List_merge(list, p3); // 金卡会员信息文件 (8折)
    list = S_List_merge(list, p4); // 白金会员信息文件 (7折)

    //    system("clear");
    U_node *pt = S_List_find_name(list, data.name); // 查找到总链表中的登录用户指针
    printf("用户名:%s\t身份码:%d\n", pt->data.name, pt->data.grade);
    printf("班次    机型        起点站  终点站  起飞时间    到达时间    飞行时间    票价  载客量  剩余座位  是否飞\n");
    printf("--------------------------------------------------------------------------------------------------\n");

    if (pt->data.ticket_num == 0)
    {
        printf("订单为空\n");
    }
    for (int i = pt->data.ticket_num; i > 0; i--)
    {
        printf("%d\t", pt->data.ticket[i - 1].id);
        printf("%s\t", pt->data.ticket[i - 1].flighttype);
        printf("%s\t", pt->data.ticket[i - 1].startcity);
        printf("%s\t", pt->data.ticket[i - 1].arrivecity);
        printf("%d:%d\t", pt->data.ticket[i - 1].starttime[0], pt->data.ticket[i - 1].starttime[1]);
        printf("%d:%d\t", pt->data.ticket[i - 1].arrivetime[0], pt->data.ticket[i - 1].arrivetime[1]);
        printf("%s\t", pt->data.ticket[i - 1].flytime);
        printf("%d\t", pt->data.ticket[i - 1].value);
        printf("%d\t", pt->data.ticket[i - 1].maxNUM);
        printf("%d\t", pt->data.ticket[i - 1].leftbuyersa);
        printf("%c\n", pt->data.ticket[i - 1].whetherfly);
    }
    F_list *p = D_List_init();
    D_List_file_scanf(p);

    sleep(3);
    system("clear");
    return user(p, data);
}
//===================================飞机图案====================================================================

void fly()
{
    int plane_x = 0;   // 飞机初始位置
    int direction = 1; // 1 表示向右，-1 表示向左
    // char input;

    while (1)
    {
        system("clear");
        draw_plane(plane_x);

        // 延时以模拟动画效果
        usleep(40000); // 等待0.1秒

        // 更新飞机位置
        plane_x += direction;

        // 当飞机到达屏幕边缘时反转方向
        // if (plane_x >= WIDTH - strlen(PLANE_CHAR) || plane_x < 0) {
        //     direction *= -1;
        // }
        if (plane_x >= WIDTH - strlen(PLANE_CHAR) || plane_x < 0)
        {
            system("clear");
            return;
        }

        // 检查是否接收到退出信号（这里简化为不处理用户输入，仅自动循环）
        // 如果需要处理用户输入，可以添加相应的代码来读取并处理它
    }
}
void draw_plane(int x)
{
    // 绘制背景（可选，这里只打印空格作为背景）
    for (int i = 0; i < WIDTH; i++)
    {
        if (i == x)
        {
            printf("%s", PLANE_CHAR); // 在指定位置打印飞机
        }
        else
        {
            printf(" ");
        }
    }
    printf("\n");
}
